package github.saw96x.remoting.transport.socket;

import github.saw96x.common.factory.SingletonFactory;
import github.saw96x.common.utils.threadpool.ThreadPoolFactoryUtil;
import github.saw96x.config.CustomShutdownHook;
import github.saw96x.config.RpcServiceConfig;
import github.saw96x.provider.Impl.ZkServiceProviderImpl;
import github.saw96x.provider.ServiceProvider;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;

/**
 * @author Saw96x
 * @date 2022/3/18 20:51
 */
@Slf4j
public class SocketRpcServer {

  private final ExecutorService threadPool;
  private final ServiceProvider serviceProvider;


  public SocketRpcServer() {
    threadPool = ThreadPoolFactoryUtil.createCustomThreadPoolIfAbsent("socket-server-rpc-pool");
    serviceProvider = SingletonFactory.getInstance(ZkServiceProviderImpl.class);
  }

  public void registerService(RpcServiceConfig rpcServiceConfig) {
    serviceProvider.publishService(rpcServiceConfig);
  }

  public void start() {
    try (ServerSocket server = new ServerSocket()) {
      String host = InetAddress.getLocalHost().getHostAddress();
      server.bind(new InetSocketAddress(host, 9998));
      CustomShutdownHook.getCustomShutdownHook().clearAll();
      Socket socket;
      while ((socket = server.accept()) != null) {
        log.info("client connected [{}]", socket.getInetAddress());
        threadPool.execute(new SocketRpcRequestHandlerRunnable(socket));
      }
      threadPool.shutdown();
    } catch (IOException e) {
      log.error("occur IOException:", e);
    }
  }

}
